//============================================================================
// Name        : SalasChat.cpp
// Author      : Facundo
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================


#include <stdlib.h>
#include <string.h>

#include "signal/SIGINT_Handler.h"
#include "signal/SignalHandler.h"

#include "Salas.h"
#include "Accion.h"
#include "ColadeMensajes/ColadeMensajes.h"

#include "ClienteUsuario.h"

using namespace std;

int main(int argc, char* argv[]) {

	//TODO: Hay q meter todo lo referente a parseo de parametros en una funcion
	int modo = 0;

	bool debug = false;
	string nombre;
	if (argc > 1) {
		if (strcmp(argv[1], "-s") == 0) {
			modo = 1;
			cout << "Modo Servidor" << endl;
		} else {
			if (strcmp(argv[1], "-c") == 0) {
				modo = 2;
				cout << "Modo Cliente" << endl;
			}

		}
		if (argc > 2) {
			if (strcmp(argv[2], "-d") == 0) {
				debug = true;
				cout << "Modo debug" << endl;
			} else {
				if (strcmp(argv[2], "-n") == 0) {

					debug = false;
					cout << "Modo Normal" << endl;
				}
			}

			if ((argc > 3) && (modo == 2)) {
				nombre = argv[3];
				cout << "Nombre del Cliente:" << nombre << endl;

			}
		}

	}

	if (modo == 1) {

// === Servidor =========
		int pid = fork();
		if (pid == 0) {
			//cout<<"pid:"<<pid<<endl;
			Salas* salas = new Salas(debug);
			Cola<Mi_Tipo_Mensaje>* cola = new Cola<Mi_Tipo_Mensaje> (
					(char *) "/bin/ls", 1);
			int res=0;
			do {

				Mi_Tipo_Mensaje mensaje;

				cola->leer(PETICION, &mensaje);

				Accion* accion1 = new Accion(mensaje,debug);
				res=accion1->Actuar(salas);

				delete (accion1);

			} while (res!=-1);
			//salas->~Salas();
			delete (salas);
			cola->~Cola();
			delete cola;


			return 0;
		} else {

			string salir;
			do {

				cin >> salir;

			} while (salir.compare("quit") != 0);
				Cola<Mi_Tipo_Mensaje>* cola = new Cola<Mi_Tipo_Mensaje> ((char *) "/bin/ls", 1);
				Mi_Tipo_Mensaje mensaje;
				mensaje.mtype = PETICION;
				mensaje.tipomensaje = TIPO_MENSAJE_SALIR;
				mensaje.pidEmisor = pid;
				mensaje.pidReceptor = 0;
				mensaje.num = 0;
				strcpy(mensaje.mensaje, "");
				mensaje.recibido = false;
				cola->escribir(mensaje);
				delete(cola);


			return 0;
		}
	} else {


// === Cliente =========

		if (modo == 2) {

			ClienteUsuario* elCliente=new ClienteUsuario(nombre,debug);
			int opcion;
			int aux;
			string s_opcion;
			system("clear");
				do {
					elCliente->imprimirOpciones();
					cin>>s_opcion;
					aux= atoi(s_opcion.c_str());
					if (aux==0){opcion=-1;}else{opcion=aux;}
					fputs("\033[A\033[2K\033[A\033[2K\033[A\033[2K\033[A\033[2K\033[A\033[2K",stdout);
					rewind(stdout);
					ftruncate(1,0);

					opcion=elCliente->atenderUsuario(opcion) ;
				} while (opcion== -1);

				if (opcion ==0) {
					elCliente->~ClienteUsuario();
					return 0;
				}

				int pid = fork();

				if (pid == 0) {

						//Escritor

						SIGINT_Handler sigint_handler;
						SignalHandler::getInstance()->registrarHandler(SIGINT,
								&sigint_handler);
						;
						do {
							// Se leen los mensajes enviados por el servidor, y se imprimie en pantalla la informacion para el usuario
							elCliente->procesarMensajesDelServidor();

						} while (sigint_handler.getGracefulQuit()==0);

					} else {
						//Lector
     					elCliente->chatear(nombre);
						kill(pid, SIGINT);
					}
		}
	}

	return 0;

}
